package iseeqq.context;

import java.awt.Image;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

import iseeqq.context.Listener.QQListener;
import iseeqq.img.FingerPrint;
import iseeqq.model.ImgCut;
import iseeqq.model.QQMsg;
import iseeqq.tool.ClipboardUtil;
import iseeqq.tool.ImgUtil;
import iseeqq.tool.QQ;
import iseeqq.tool.ScreenShot;
import iseeqq.tool.Source;

/**
 * 
 * 
 * @author 戴永杰
 *
 * @date 2017年11月14日 下午5:36:03
 * @version V1.0
 *
 */
public class QQContext {

	private static Logger logger = Logger.getLogger(QQContext.class);

	Robot robot;

	public QQContext(Robot robot) {
		super();
		this.robot = robot;
	}

	public int getQqStatus() {
		return qqStatus;
	}

	public String getQqStatusMsg() {

		switch (qqStatus) {
		case -2:
			return "未识别到QQ图标位置";
		case -1:
			return "QQ程序未启动";
		case 0:
			return "QQ离线了";
		case 1:
			return "QQ在线中";
		default:
			logger.debug("未识别状态" + qqStatus);
			return "";
		}
	}

	public void setQqStatus(int qqStatus) {
		this.qqStatus = qqStatus;
	}

	public ImgCut getQqPost() {
		return qqTaskPost;
	}

	public void setQqPost(ImgCut qqPost) {
		this.qqTaskPost = qqPost;
	}

	/**
	 * -1 未找到 0 离线 1 在线
	 */
	private int qqStatus = 0;

	/**
	 * 处于扫描中状态
	 */
	private boolean scan;

	public boolean isScan() {
		return scan;
	}

	public void setScan(boolean scan) {
		this.scan = scan;
	}

	/**
	 * QQ任务栏图标位置
	 */
	private ImgCut qqTaskPost;
	
	/**
	 * QQ聊天窗口位置
	 */
	private ImgCut qqChatWindow;

	public void addListerner(QQListener qqListener) {
		// 比较两图片的相似度

		try {
			BufferedImage curQQPost = getCurQQPost();
			float compare = new FingerPrint(qqTaskPost.getImg()).compare(new FingerPrint(curQQPost));
			if (compare > 0.80) { // 相似度
				if (QQ.getQQStatus(curQQPost) == 0) {
					Window.outPic(qqTaskPost.getImg(), "img/标准.png");
					Window.outPic(curQQPost, "img/离线中.png");
					logger.debug("QQ离线中" + compare);
					System.exit(-1);
					this.scan = false;
				} else {
					// logger.debug("等待接收消息");
					Thread.sleep(1000);
				}
			} else {

				qqChatWindow = openWindow();
				if (qqChatWindow != null) {
					int messageCode = getMessageCode();
					handleMessage(messageCode, null, qqListener);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public synchronized int getMessageCode() {

		if ("验证消息".equals(qqChatWindow.getTitle())) {
			return 0;
		}
		// 暂时关闭
		// int[] hongBao = checkRedBag(openWindow);// 有红包啦
		// if (hongBao != null) {
		// readRedBag(openWindow, hongBao);
		// return hongBao[0];
		// }
		return 1;
	}

	/**
	 * 
	 * @param openWindow
	 * @return 0[系统消息] 1[消息] 2[普通红包] 3 口令红包
	 */
	public synchronized int[] checkRedBag(ImgCut openWindow) {

		int[] result = null;
		int[] checkImagePatch = ImgUtil.checkImagePatch(Source.pthbImage, openWindow.getImg());
		if (checkImagePatch != null) {
			// 检测红包的位置处理
			result = new int[3];
			result[0] = 2; // 普通红包
			result[1] = openWindow.getX() + checkImagePatch[0] + 70;
			result[2] = openWindow.getY() + checkImagePatch[1] + 70;
		}
		checkImagePatch = ImgUtil.checkImagePatch(Source.klhbImage, openWindow.getImg());
		if (checkImagePatch != null) {
			// 检测红包的位置处理
			result = new int[3];
			result[0] = 3; // 口令红包
			result[1] = openWindow.getX() + checkImagePatch[0] + 70;
			result[2] = openWindow.getY() + checkImagePatch[1] + 70;
		}
		return result;
	}

	/**
	 * 
	 * @param type
	 *            0[系统消息] 1[消息] 2[普通红包] 3 口令红包
	 * @param qqListener
	 */
	public synchronized void handleMessage(int type, QQMsg readQQMsg, QQListener qqListener) {
		if (qqListener == null)
			return;

		switch (type) {
		case 0: // 系统消息 直接关闭
			Window.closeWindow(qqChatWindow, robot);
			break;
		case 1:
			if (readQQMsg == null)
				readQQMsg = readQQMsg();

			handlerMessageListener(qqListener, readQQMsg);
			break;
		default:
			break;
		}
		repeatQQ(type, qqListener);
	}

	private final static String msgHeadRegExp = "(.*)\\((.+)\\)\\s+([0-9]{1,2}:[0-9]{2}:[0-9]{2})";

	/**
	 * 备用方法
	 * 
	 * @param qqListener
	 * @param readQQMsg
	 * @param openWindow
	 */
	public void handlerMessageListener__(QQListener qqListener, QQMsg readQQMsg, ImgCut openWindow) {
		int type = QQ.getQQType(openWindow.getImg());
		QQMsg qqmess = new QQMsg();

		String line;
		List<String> context = readQQMsg.getContext();
		for (int j = 0; j < context.size(); j++) {
			line = context.get(j).trim();
			if (line.length() == 0)
				continue;
			if (context.get(j).matches(msgHeadRegExp)) {
				Pattern pat = Pattern.compile(msgHeadRegExp);
				Matcher mat = pat.matcher(line);
				qqmess = new QQMsg();
				if (mat.find()) {
					qqmess.setType(type);
					qqmess.setNickName(mat.group(1).trim());
					qqmess.setAccount(mat.group(2).trim());
					qqmess.setTime(strToDate(mat.group(3).trim()));
				}
			} else {
				qqmess.append(line);
				qqListener.onMessage(openWindow.getTitle(), qqmess);
			}
		}
	}

	private Date strToDate(String date) {
		try {
			LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.parse(date));
			Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
			return Date.from(instant);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 备用方案
	 * 
	 * @param qqListener
	 * @param openWindow
	 */
	private void handlerMessageListener(QQListener qqListener, QQMsg readQQMsg) {
		int type = QQ.getQQType(qqChatWindow.getImg());
		QQMsg qqmess = new QQMsg();

		List<String> context = readQQMsg.getContext();
		if (context.isEmpty())
			return;
		Iterator<String> iterator = context.iterator();
		String next = iterator.next();
		if (next.trim().length() == 0)
			iterator.remove();

		boolean isText = false;

		for (int i = 0; i < context.size(); i++) {
			if (context.get(i).trim().length() == 0)
				continue;
			String[] split = context.get(i).split(" ");
			Date msgTime = getMsgTime(split);

			if (msgTime == null)
				isText = true;
			else
				isText = false;
			if (!isText) {

				if (qqmess.getALLContext().size() > 0) {
					qqListener.onMessage(qqChatWindow.getTitle(), qqmess);
				}
				qqmess = new QQMsg();
				qqmess.setType(type);
				qqmess.setTime(msgTime);

				if (type == 1) {
					qqmess.setNickName(qqChatWindow.getTitle());
				} else {
					qqmess.setNickName(getNickName(context.get(i)));
					qqmess.setAccount(getAccount(context.get(i)));
				}

			} else {
				qqmess.append(context.get(i));
			}
		}
		// 输最后一条
		if (qqmess.getALLContext().size() > 0) {
			qqListener.onMessage(qqChatWindow.getTitle(), qqmess);
		}
	}

	public String getAccount(String context) {

		if (context.lastIndexOf('(') > 0) {
			context = context.substring(context.lastIndexOf('(') + 1, context.lastIndexOf(')')).trim();
			return context;
		}
		if (context.lastIndexOf("&lt;") > 0) {
			context = context.substring(context.lastIndexOf("&lt;") + 4, context.lastIndexOf("&gt;")).trim();
			return context;
		}
		return null;
	}

	public String getNickName(String context) {
		if (context.lastIndexOf("(") > 0) {
			context = context.substring(0, context.lastIndexOf("(")).trim();
			return context;
		}
		if (context.lastIndexOf("&lt;") > 0) {
			context = context.substring(0, context.lastIndexOf("&lt;")).trim();
			return context;
		}

		return null;

	}

	private Date getMsgTime(String[] split) {
		String date = split[split.length - 1];
		if (date.trim().length() == 0)
			return null;
		try {
			LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(),
					LocalTime.parse(date, DateTimeFormatter.ofPattern("H:mm:ss")));
			Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
			return Date.from(instant);
		} catch (Exception e) {
			return null;
		}

	}

	public synchronized void writeQQMsg(QQMsg qqmsg) {
		for (Object msg : qqmsg.getALLContext()) {
			if (msg instanceof String) {
				String msgStr = ((String) msg).trim();
				if (msgStr.trim().length() != 0)
					ClipboardUtil.setSysClipboardText(msgStr);
			} else if (msg instanceof File) {
				Image imgObj = null;
				try {
					imgObj = ImageIO.read((File) msg);
				} catch (IOException e) {
					e.printStackTrace();
				}
				ClipboardUtil.setClipboardImage(imgObj);

			} else if (msg instanceof Image) {
				ClipboardUtil.setClipboardImage((Image) msg);
			}
			// 粘贴
			robot.delay(interval);
			robot.keyPress(KeyEvent.VK_CONTROL);
			robot.keyPress(KeyEvent.VK_V);
			robot.keyRelease(KeyEvent.VK_V);
			robot.keyRelease(KeyEvent.VK_CONTROL);
			robot.delay(interval);
			// shift+enter
			robot.keyPress(KeyEvent.VK_SHIFT);
			robot.keyPress(KeyEvent.VK_ENTER);
			robot.keyRelease(KeyEvent.VK_ENTER);
			robot.keyRelease(KeyEvent.VK_SHIFT);

		}
		// 发送出去 enter
		robot.keyPress(KeyEvent.VK_ENTER);
		robot.keyRelease(KeyEvent.VK_ENTER);

		//清屏
		clsWinQQMessage();
	}

	/**
	 * 指定QQ好发送消息
	 * 
	 * @param name
	 * @param msg
	 */
	@Deprecated
	public synchronized void writeQQMsg(String name, QQMsg msg) {

		robot.mouseMove(qqTaskPost.getX() + 3, qqTaskPost.getY() + 3);
		// 右键
		robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
		ClipboardUtil.setSysClipboardText(name);

		// 上 上 回车
		robot.delay(interval);
		robot.keyPress(KeyEvent.VK_UP);
		robot.keyRelease(KeyEvent.VK_UP);
		robot.delay(interval);
		robot.keyPress(KeyEvent.VK_UP);
		robot.keyRelease(KeyEvent.VK_UP);
		robot.delay(interval);
		robot.keyPress(KeyEvent.VK_ENTER);
		robot.keyRelease(KeyEvent.VK_ENTER);
		robot.delay(interval);

		ImgCut qqWin = Window.getForegroundWindowPost(robot);
		robot.mouseMove(qqWin.getX() + 10, qqWin.getX() + 10);
		robot.delay(interval);
		// // 左键
		// robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
		// robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
		// robot.delay(interval);
		// ctrl+V
		robot.keyPress(KeyEvent.VK_CONTROL);
		robot.keyPress(KeyEvent.VK_V);
		robot.keyRelease(KeyEvent.VK_V);
		robot.keyRelease(KeyEvent.VK_CONTROL);
		robot.delay(interval);
		robot.keyPress(KeyEvent.VK_ENTER);
		robot.keyRelease(KeyEvent.VK_ENTER);
		robot.delay(interval);

		writeQQMsg(msg);
	}

	private int interval = 200;

	/**
	 * 读取消息，并进行清屏操作（防止存在重复消息）
	 */
	public synchronized QQMsg readQQMsg() {
		robot.mouseMove(qqChatWindow.getX() + qqChatWindow.getW() / 2, qqChatWindow.getY() + qqChatWindow.getH() / 2);
		// 鼠标左键
		robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);

		// robot.keyPress(KeyEvent.VK_TAB);
		// robot.keyRelease(KeyEvent.VK_TAB);

		robot.delay(interval);
		robot.keyPress(KeyEvent.VK_CONTROL);
		robot.keyPress(KeyEvent.VK_A);
		robot.keyRelease(KeyEvent.VK_A);
		robot.delay(100);
		robot.keyPress(KeyEvent.VK_C);
		robot.keyRelease(KeyEvent.VK_C);
		robot.keyRelease(KeyEvent.VK_CONTROL);
		robot.delay(interval);
		// 读取完之后立即清屏
		clsWinQQMessage();
		robot.delay(interval);
		return ClipboardUtil.getSystemClipboardQQ();
	}

	public synchronized void readRedBag(ImgCut qqWindow, int[] hongBao) {
		robot.mouseMove(hongBao[1], hongBao[2]);
		robot.delay(interval);
		robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
		robot.delay(interval + 500);// 防止延迟

		if (hongBao[0] == 2) {

			// 关闭窗口
			ImgCut foregroundWindowPost = Window.getForegroundWindowPost(robot);
			robot.mouseMove(foregroundWindowPost.getX() + foregroundWindowPost.getW() - 30,
					foregroundWindowPost.getY() + 20);
			robot.delay(interval);
			robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
			robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
			robot.delay(interval);
		} else if (hongBao[0] == 3) {
			ImgCut foregroundWindowPost = Window.getForegroundWindowPost(robot);
			// Window.outPic(foregroundWindowPost.getImg(), "img/temp.png");
			int[] checkImagePatch = ImgUtil.checkImagePatch(Source.srklImage, foregroundWindowPost.getImg());
			if (checkImagePatch != null) {
				robot.mouseMove(foregroundWindowPost.getX() + checkImagePatch[0] + 50,
						foregroundWindowPost.getY() + checkImagePatch[1] + 35);
				robot.delay(interval);
				robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
				robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
				robot.delay(interval);

				robot.keyPress(KeyEvent.VK_ENTER);
				robot.keyRelease(KeyEvent.VK_ENTER);
				robot.delay(interval);

				// 关闭窗口
				foregroundWindowPost = Window.getForegroundWindowPost(robot);
				robot.mouseMove(foregroundWindowPost.getX() + foregroundWindowPost.getW() - 30,
						foregroundWindowPost.getY() + 20);
				robot.delay(interval);
				robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
				robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
				robot.delay(interval);
			}
		}
	}

	/**
	 * 清屏操作
	 */
	public void clsWinQQMessage() {
		robot.mouseMove(qqChatWindow.getX() + qqChatWindow.getW() / 2, qqChatWindow.getY() + qqChatWindow.getH() / 2);
		// 右键
		robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
		// 方向 up 清屏
		robot.keyPress(KeyEvent.VK_UP);
		robot.keyRelease(KeyEvent.VK_UP);
		robot.delay(interval);
		// 回车
		robot.keyPress(KeyEvent.VK_ENTER);
		robot.keyRelease(KeyEvent.VK_ENTER);
		robot.delay(interval);
		// robot.keyPress(KeyEvent.VK_F10);
		// robot.keyRelease(KeyEvent.VK_F10);
	}

	public synchronized void repeatQQ(int type, QQListener qqListener) {
		QQMsg readQQMsg = readQQMsg();
		// logger.debug("repeatQQ:" + readQQMsg.getContext());
		if (readQQMsg.getContext().size() == 0) {
			clearQQWindow();
			return;
		}
		// 进入循环地，读取消息-> 推送消息
		handleMessage(type, readQQMsg, qqListener);
	}

	public void clearQQWindow() {
		// 关闭窗口
		Window.closeWindow(qqChatWindow, robot);
		// robot.keyPress(KeyEvent.VK_CONTROL);
		// robot.keyPress(KeyEvent.VK_W);
		// robot.keyRelease(KeyEvent.VK_CONTROL);
		// robot.delay(interval);

		if ("提示".equals(Window.getForegroundWindowPost(robot) .getTitle())) {
			robot.keyPress(KeyEvent.VK_ENTER);
			robot.keyRelease(KeyEvent.VK_ENTER);
			robot.delay(interval);
		}

		// 清空剪贴板
		ClipboardUtil.clear();
	}

	public ImgCut openWindow() {
		robot.mouseMove(qqTaskPost.getX() + 5, qqTaskPost.getY());
		robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
		robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
		robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
		robot.delay(500);

		ImgCut foregroundWindowPost = Window.getForegroundWindowPost(robot);
		if (qqTaskPost.getPid() != foregroundWindowPost.getPid()) {
			return null;
		}
		if ("QQ".equals(foregroundWindowPost.getTitle())) { // 打开失败 关闭窗口.
			Window.minimizeWindow(Window.getForegroundWindowPost(robot), robot);
			return null;
		}
		logger.debug("===============================窗口[" + foregroundWindowPost.getTitle()+"]");
		return foregroundWindowPost;
	}

	public BufferedImage getCurQQPost() {
		return ScreenShot.getScreen(robot, qqTaskPost.getX(), qqTaskPost.getY(), qqTaskPost.getW(), qqTaskPost.getH());
	}

}
